#include "cfg.h"
using namespace std;

//构造函数
Config::Config(string file_name)
{
    //定义一个配置文件
    this->file_name = file_name;
    //默认一共0个配置
    this->cfg_line = 0;
    if (createHead() == 0)
    {
        //从文件读取全部配置 加入链表
        getCFG();
        //打印全部配置
        //printCfg();
    }
}

//析构函数
Config::~Config()
{
    //释放链表的各个节点
    freeJoin();
    //释放头节点
    if (this->head != NULL)
    {
        delete this->head;
    }
}

//获取配置的总数
int Config::getLines()
{
    return this->cfg_line;
}

//设置某个配置项
int Config::setCFG(string key, string value)
{
    int rt = 0;
    //插入链表
    joinHead(key, value);
    //同步到文件
    inputFile();
    return rt;
}

//内存配置同步到文件
int Config::inputFile()
{
    int rt = 1;
    if (this->head == NULL)
    {
        return rt;
    }
    //缓存字符串
    string st;
    //定义文件类型
    ofstream outfile;
    //打开文件方式
    outfile.open(this->file_name.c_str() , ios_base::out | ios_base::out | ios_base::trunc);
    // 遍历向文件写入用户输入的数据
    CFG_J * p = this->head->next;
    while (p != NULL)
    {
        //定义字符串
        st = p->key + "=" + p->value;
        //写入字符串
        outfile << st << endl;
        //移动指针
        p = p->next;
    }
    //关闭文件
    outfile.close();
    return rt;
}

//获取某项特定配置
string Config::getCFG(string key)
{
    //默认找不到
    string rt = "CANNOT FIND THIS CONFIG.";
    if (this->head == NULL)
    {
        return rt;
    }
    //遍历抓取配置项
    CFG_J *p = this->head->next;
    while (p != NULL)
    {
        if (p->key.compare(key) == 0)
        {
            //捕捉到则返回值
            rt = p->value;
            break;
        }
        p = p->next;
    }
    return rt;
}

//从文件获取全部的配置
int Config::getCFG()
{
    int rt = 0;
    //先清空链表
    freeJoin();
    //配置总数为0
    this->cfg_line = 0;
    //定义缓存字符串变量
    string st;
    string key, value;
    //定义文件变量
    ifstream infile;
    string::size_type idx;
    char *p = NULL, *q = NULL;
    //打开文件
    infile.open(this->file_name.c_str());
    //遍历直到文件的最后
    while (!infile.eof())
    {
        //初始化缓存
        st = "";
        //取得一行配置
        infile >> st;
        //找不到等号则继续
        idx = st.find("=");
        if (idx == string::npos)
        {
            continue;
        }
        //截断字符串得到key和value字符串
        key = st.substr(0, idx);
        value = st.substr(idx + 1,st.length()-idx);
        //插入链表
        joinHead(key,value);
    }
    //关闭文件
    infile.close();
    return rt;
}

//将配置插入内存链表
int Config::joinHead(string key,string value)
{
    int rt = 1;
    if (this->head == NULL)
    {
        rt = 2;
        return rt;
    }
    //定义移动指针
    CFG_J * p = this->head;
    CFG_J * cur = p->next;
    while (cur != NULL)
    {
        //cout << cur->key << " " << key << " " << cur->key.compare(key) << endl;
        //找到值则直接改变
        if (cur->key.compare(key) == 0)
        {
            cur->value = value;
            rt = 0;
            break;
        }
        p = cur;
        cur = p->next;
    }
    //找不到值则再最后插入
    if (rt != 0)
    {
        CFG_J *q = new CFG_J();
        q->key = key;
        q->value = value;
        q->next = NULL;
        p->next = q;
        //配置数自增
        this->cfg_line ++;
    }
    return rt;
}

//释放全部节点（除了头指针）
int Config::freeJoin()
{
    int rt = 1;
    //定义移动指针
    CFG_J * p = this->head->next;
    CFG_J * cur = p;
    if (p == NULL)
    {
        return rt;
    }
    //遍历释放内存
    while (cur != NULL)
    {
        p = cur->next;
        delete cur;
        cur = p;
    }
    //初始化头指针
    this->head->next = NULL;
    rt = 0;
    return rt;
}

//打印所有的配置
void Config::printCfg()
{
    if (this->head == NULL)
    {
        return;
    }
    //定义移动指针
    CFG_J * p = this->head->next;
    while (p != NULL)
    {
        cout << p->key << "=" << p->value << endl;
        //移动指针
        p = p->next;
    }
}

//创建配置链表头指针
int Config::createHead()
{
    int rt = 1;
    CFG_J *p = new CFG_J();
    p->key = "headkey";
    p->value = "headvalue";
    p->next = NULL;
    this->head = p;
    rt = 0;//没有问题
    return rt;
}
